<?php

namespace App\V3\V3_2_7\Controllers;

use App\Services\CommonService;
use App\V3\V3_2_7\Models\MaterielProductContentModel;
use App\V3\V3_2_7\Models\MaterielsTypeModel;
use App\V3\V3_2_7\Models\MaterielTypeModel;
use App\V3\V3_2_7\Models\StorageManageModel;
use App\V3\V3_2_7\Services\StorageManageService;
use App\Helper\Utils\Util;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Validator;
use App\V3\V3_2_7\Services\MaterielTypeService;
use App\V3\V3_2_7\Models\HcMaterielTypeModel;
use OSS\OssClient;
use App\V3\V3_2_7\Models\MaterielClassModel;
use App\V3\V3_2_7\Models\StorageModel;
use App\V3\V3_2_7\Models\StorageShelfModel;
use App\V3\V3_2_7\Models\StorageShelfLocationModel;
use App\Rules\JsonArray;
use App\V3\V3_2_7\Models\AdminModel;

class MaterielTypeController extends BaseController
{
    /**
     * 创建物料商品信息
     * @param Request $request
     * AUTHOR  : zlf
     * DateTime: 2023/9/5 15:51
     * @return \Illuminate\Http\JsonResponse
     */
    public function add(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'materiel_name' => 'required',//物料或套件名称
            /*'two_materiel_name' => 'required',//第二商品名称*/
            'is_product_materiel' => [
                Rule::In([0, 1]),
            ],//是否为套件;0:否;1:是;
            'materiel_class_id' => [
                'required',
                'integer',
                Rule::notIn([0]),
            ],//物料类型所属二级分类id
            'length' => 'nullable|numeric|min:0',//长
            'width' => 'nullable|numeric|min:0',//宽
            'height' => 'nullable|numeric|min:0',//高
            'weight' => 'nullable|numeric|min:0',//体积
            'is_use_serial' => [
                Rule::in([0, 1])
            ],
            'goods_spce_info' => [
                'required',
                'json',
            ],
        ],
            [
                'is_product_materiel.in' => '商品类型异常：仅支持商品或套件',
                'materiel_name.required' => '请填写名称',
                /*'two_materiel_name.required' => '请填写第二名称',*/
                'materiel_class_id.required' => '请选择商品类型所属分类id',
                'length.numeric' => '商品长度只能为数字',
                'length.min' => '商品长度最小只能为0',
                'width.numeric' => '商品宽度只能为数字',
                'width.min' => '商品宽度最小只能为0',
                'height.numeric' => '商品高度只能为数字',
                'height.min' => '商品高度最小只能为0',
                'weight.numeric' => '商品体积只能为数字',
                'weight.min' => '商品体积最小只能为0',
                'is_use_serial.in' => '参数`是否使用序列号`不合法',
                'goods_spce_info.required' => '参数`goods_spce_info`缺失',
                'goods_spce_info.json' => '参数`goods_spce_info`仅能为json',
            ]);
        if ($info = $validator->errors()->first())
            return fail('', $info);
        $time = time();
        $this->operateLog('新建物料', $data, $time);
        /*  $data['length'] = $data['length']??'';
          $data['width'] = $data['width']??'';
          $data['height'] = $data['height']??'';
          $data['weight'] = $data['weight']??'';*/
        $data['main_id'] = $this->getMainUserId();
        $data['user_id'] = $this->getUserId();
        $data['created_at'] = $time;
        $data['add_type'] = $data['add_type'] ?? 0;
        $data['alert_num'] = $data['alert_num'] ?? 0;
        $data['price_type'] = $data['price_type'] ?? 0;
        $data['remark'] = $data['remark'] ?? '';
        $data['attribute'] = $data['attribute'] ?? '';
        $data['storage_id'] = $data['storage_id'] ?? 0;
        $data['in_storage_num'] = $data['in_storage_num'] ?? 0;
        $data['serial_info'] = $data['serial_info'] ?? [];
        $data['shelf_id'] = $data['shelf_id'] ?? 0;
        $data['location_id'] = $data['location_id'] ?? 0;
        $data['label_id'] = $data['label_id'] ?? '';
        $data['label_name'] = $data['label_name'] ?? '';
        $data['texture'] = $data['texture'] ?? '';
        $data['executive_standard'] = $data['executive_standard'] ?? '';
        $data['is_use_serial'] = $data['is_use_serial'] ?? 0;
        $time = time();
        $data['in_storage_time'] = $data['in_storage_time'] ?? $time;
        $data['batch_title'] = $this->batchTitle();
        $data['goods_supplier_name'] = $data['goods_supplier_name'] ?? '';
        $data['goods_client_name'] = $data['goods_client_name'] ?? '';
        $data['goods_storage_name'] = $data['goods_storage_name'] ?? '';
        if ($data['add_type']) {
            if (empty($data['storage_id'])) {
                return fail('', '请选择入库仓库');
            }
        }
        $logData = '商品名称：' . $data['materiel_name'] . '数量：' . count(json_decode($data['goods_spce_info'], true));
        $this->operateLog('新建商品', $data, $time, $logData);
        return MaterielTypeService::handleGoodsSpceInfo($data, $time, $this->isUseShelf(), [], __FUNCTION__);//处理商品规格数据
    }

    public function del(Request $request)
    {
        if (empty($request->id)) {
            return $this->fail('', '参数`物料商品id`缺失');
        }

        $arr = array_filter(explode(',', $request->id), function ($v) {
            return $v !== '';
        });

        /*$checkTypeInfo = StorageManageModel::where('delete_flag', 0)
            ->where('in_storage_num', '!=', 0)
            ->whereIn('type_id', $arr)->first();

        if (!empty($checkTypeInfo)) {
            return $this->fail('', '若需要删除该物料类型，需删除该类型下所有的在库数据');
        }*/
        $goodsList = MaterielsTypeModel::select('materiel_name', 'materiel_no')
            ->whereIn('id', $arr)->get()->toArray();
        $logData = '';
        if (!empty($goodsList)) {
            foreach ($goodsList as $val) {
                $logData .= '商品名称：' . $val['materiel_name'] . '（' . $val['materiel_no'] . '）' .
                    '已删除,';
            }
        }
        DB::beginTransaction();

        try {
            MaterielsTypeModel::whereIn('id', $arr)->update(['delete_flag' => 1]);
            StorageManageModel::query()
                ->whereIn('type_id', $arr)->update(['delete_flag' => 1]);

            MaterielProductContentModel::whereIn('product_id', $arr)->update(['delete_flag' => 1]);
            $this->log('删除物料类型', $arr, $logData);
            DB::commit();
            return $this->success();
        } catch (Exception $e) {
            DB::rollBack();
            return $this->fail('', $e->getMessage());
        }
    }

    /**
     * 编辑商品详细
     * @param Request $request
     * AUTHOR  : zlf
     * DateTime: 2023/9/6 9:37
     * @return \Illuminate\Http\JsonResponse
     */
    public function edit(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'id' => 'required',//物料名称
            'materiel_name' => 'required',//物料名称
            /*'two_materiel_name' => 'required',//物料名称*/
            'materiel_class_id' => [
                'required',
                'integer',
                Rule::notIn([0]),
            ],//物料类型所属二级分类id
        ],
            [
                /*'two_materiel_name.required' => '请填写第二商品名称',*/
                'id.required' => '参数`物料商品id`缺失',
                'materiel_name.required' => '请填写商品名称',
                'materiel_class_id.required' => '请选择商品类型所属分类id',
            ]
        );

        if ($info = $validator->errors()->first()) {
            return fail('', $info);
        }
        $time = time();
        $logData = '商品名称：' . $data['materiel_name'] . '信息已更新！';
        $this->operateLog('修改商品', $data, $time, $logData);
        $data['length'] = isset($data['length']) ? ($data['length'] < 0) ? 0 : $data['length'] : 0;
        $data['is_product_materiel'] = !isset($data['is_product_materiel']) ? 0 : $data['is_product_materiel'];
        $data['width'] = isset($data['width']) ? ($data['width'] < 0) ? 0 : $data['width'] : 0;
        $data['height'] = isset($data['height']) ? ($data['height'] < 0) ? 0 : $data['height'] : 0;
        $data['weight'] = isset($data['weight']) ? ($data['weight'] < 0) ? 0 : $data['weight'] : 0;
        $data['is_use_serial'] = empty($data['is_use_serial']) ? 0 : 1;
        $data['main_id'] = $this->getMainUserId();
        $data['user_id'] = $this->getUserId();
        $data['updated_at'] = $time;
        $data['alert_num'] = empty($data['alert_num']) ? 0 : $data['alert_num'];
        $data['remark'] = empty($data['remark']) ? '' : $data['remark'];
        $data['attribute'] = empty($data['attribute']) ? '' : $data['attribute'];
        $data['texture'] = empty($data['texture']) ? '' : $data['texture'];
        $data['executive_standard'] = empty($data['executive_standard']) ? '' : $data['executive_standard'];
        $goodsInfo = MaterielTypeService::goodsInfo($data);
        if ($goodsInfo->materiel_img != '') {
            MaterielTypeService::materielTypeImgResize($goodsInfo->materiel_img);//生成缩略图片
        }

        if (!empty($goodsInfo)) {
            if ($goodsInfo['is_use_serial'] != $data['is_use_serial']) {
                $storageManageInfo = StorageManageModel::where([
                    'type_id' => $goodsInfo['id'],
                    'delete_flag' => 0
                ])->where('in_storage_num', '>', 0)->first();
                if (!empty($storageManageInfo)) {
                    if ($data['is_use_serial'] == 1) {
                        return fail('', '库存中存在该商品，不能开启序列号，需清空库存');
                    } else {
                        return fail('', '库存中存在该商品，不能关闭序列号，需清空库存');
                    }
                }
            }

            return MaterielTypeService::handleGoodsSpceInfo($data, $time, $this->isUseShelf(), $goodsInfo, __FUNCTION__);
        } else {
            return fail('', '物料商品信息，不存在！');
        }
    }

    /**
     * 获取物料商品指定信息
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/5 9:39
     * @return \Illuminate\Http\JsonResponse
     */
    public function info(Request $request)
    {
        if (empty($request->id)) {
            return $this->fail('', '参数`物料类型id`缺失');
        }
        $info = MaterielTypeService::info($request->id);
        $addminInfo = AdminModel::select(
            'company_name',
            'mobile',
            'company_address',
            'name')->from('admin as a')
            ->leftJoin('company_class as b', 'b.id', '=', 'a.company_class')
            ->where('a.id', $this->getMainUserId())->first();
        $info['company_info'] = $addminInfo;
        return $this->success($info);
    }

    /**
     * 物料列表
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/5 10:39
     * @return \Illuminate\Http\JsonResponse
     */
    public function select(Request $request)
    {
        $keyword = empty($request->keyword) ? '' : $request->keyword;
        $condition = [];

        if (!empty($request->materiel_class_id)) {
            $condition['a.materiel_class_id'] = ['EQ' => $request->materiel_class_id];
        }

        return $this->success(
            MaterielTypeService::materielTypeSelect(
                $this->getMainUserId(),
                $keyword,
                $condition,
                $request->pageSize,
                $request->currentPage,
                $request->is_product_materiel,
                $request->all()
            )
        );
    }
    public function selectGoodsList(Request $request)
    {
        $condition = [];
        $keyword = empty($request->keyword) ? '' : $request->keyword;
        if (!empty($request->materiel_class_id)) {
            $condition['a.materiel_class_id'] = ['EQ' => $request->materiel_class_id];
        }
        return $this->success(
            MaterielTypeService::selectGoodsList(
                $this->getMainUserId(),
                $keyword,
                $condition,
                $request->pageSize,
                $request->currentPage,
                $request->is_product_materiel,
                $request->all()
            )
        );
    }

    /**
     * 物料商品列表-含库存信息
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/5 11:22
     * @return \Illuminate\Http\JsonResponse
     */
    public function list(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'pageSize' => 'required',//物料名称
            'currentPage' => 'required',//成本
//            'is_product_class' => [
//                'required',
//                Rule::in([0,1])
//            ],
        ],
            [
                'pageSize.required' => '参数`页面大小`缺失',
                'currentPage.required' => '参数`页码`缺失',
//                'is_product_class' => '参数`类型`缺失'
            ]
        );

        if ($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }
        $storageIdArr = [];
        if ($this->getUserId() == $this->getMainUserId()) {
            $user['e.main_id'] = ['EQ' => $this->getMainUserId()];
        } else {
            if ($this->isShareStorage()) {
                $user['e.main_id'] = ['EQ' => $this->getMainUserId()];
            } else {
                $userInfo = [
                    'main_id' => $this->getMainUserId(),
                    'user_id' => $this->getUserId()
                ];
                $storageIdArr = CommonService::getMultiUser($userInfo);
                if (empty($storageIdArr)) {
                    $user['e.user_id'] = ['EQ' => $this->getUserId()];
                } else {
                    $user['e.main_id'] = ['EQ' => $this->getMainUserId()];
                }
            }
        }

        $data['user_id'] = $this->getUserId();
        $data['main_id'] = $this->getMainUserId();
        $data['user_type'] = $this->getUserTpye();
        $data['is_share_storage_operate'] = $this->isShareStorageOperate();
        return $this->success(MaterielTypeService::list($user, $data, $storageIdArr));

    }

    public function chooseGoodsList(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'pageSize' => 'required',
            'currentPage' => 'required',
        ],
            [
                'pageSize.required' => '参数`页面大小`缺失',
                'currentPage.required' => '参数`页码`缺失',
            ]
        );

        if ($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }
        $storageIdArr = [];
        if ($this->getUserId() === $this->getMainUserId()) {
            $user['e.main_id'] = ['EQ' => $this->getMainUserId()];
        } else {
            if ($this->isShareStorage()) {
                $user['e.main_id'] = ['EQ' => $this->getMainUserId()];
            } else {
                $userInfo = [
                    'main_id' => $this->getMainUserId(),
                    'user_id' => $this->getUserId()
                ];
                $storageIdArr = CommonService::getMultiUser($userInfo);
                if (empty($storageIdArr)) {
                    $user['e.user_id'] = ['EQ' => $this->getUserId()];
                } else {
                    $user['e.main_id'] = ['EQ' => $this->getMainUserId()];
                }
            }
        }
        $data['user_id'] = $this->getUserId();
        $data['main_id'] = $this->getMainUserId();
        $data['is_share_storage_operate'] = $this->isShareStorageOperate();
        return $this->success(MaterielTypeService::chooseGoodsList($user, $data, $storageIdArr));
    }

    public function randNo()
    {
        $data['materiel_no'] = Util::randStr(8);
        $data['main_id'] = $this->getMainUserId();

        while (!empty(MaterielsTypeModel::checkMaterielTypeRandCode($data))) {
            $data['materiel_no'] = Util::randStr(8);
        }

        unset($data['main_id']);

        return $this->success($data);
    }

    public function editMaterielCost(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'id' => 'required',//物料名称
            'cost' => 'numeric|min:0',//成本
        ],
            [
                'id.required' => '参数`物料商品id`缺失',
                /* 'cost.numeric' => '商品成本只能为数字', */
                'cost.min' => '商品成本最小只能为0',
            ]
        );

        if ($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }
        $goodsName = MaterielsTypeModel::where('id', $data['id'])->value('materiel_name');
        $logData = "商品名称：" . $goodsName . '成本价修改为：' . $data['cost'] . '元';
        $data['main_id'] = $this->getMainUserId();
        $data['user_id'] = $this->getUserId();
        $this->log('修改成本价', $data, $logData);
        MaterielTypeService::editMaterielCost($data);
        return $this->success();
    }

    public function packageInfo(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'id' => 'required',//物料名称
        ],
            [
                'id.required' => '参数`物料商品id`缺失',
            ]
        );

        if ($info = $validator->errors()->first()) {
            return $this->fail('', $info);
        }

        return $this->success(
            MaterielTypeService::packageInfo($data)
        );
    }

    /**
     * 同步修改相同商品名称信息
     * @param Request $request
     */
    public function syncEdit(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'id' => 'required',//物料id
            'upd_flag' => [
                'required',
                'integer',
                Rule::In([1, 2]),
            ],//同步修改名称/分类或其他：1、名称/分类，2，其他
        ],
            [
                'id.required' => '参数`物料商品id`缺失',
                'upd_flag.required' => '请填写商品名称',
                'upd_flag.in' => '同步修改，缺少参数：1、名称/分类，2，其他',
            ]);

        if ($info = $validator->errors()->first()) {
            return fail('', $info);
        }
        $time = time();
        $goodsName = MaterielsTypeModel::where('id', $data['id'])->value('materiel_name');
        $data['main_id'] = $this->getMainUserId();
        $data['user_id'] = $this->getUserId();
        $data['updated_at'] = $time;
        if ($data['upd_flag'] == 2) {//同步修改其他，不包括名称和分类
            $attributeArray = ['length', 'width', 'height', 'weight', 'alert_num'];
            foreach ($attributeArray as $val) {
                if (isset($data[$val])) {
                    if ($data[$val] < 0) return fail('', '参数：' . $val . ' 不能小于0');
                }
            }
            unset($data['materiel_name']);
            unset($data['materiel_class_id']);
            $requestData = $data;
            $logData = '商品名称:' . $goodsName . '同步修改其他，不包括名称和分类';
        } else {//同步修改名称和分类，不包括其他属性
            $requestData['id'] = $data['id'];
            $requestData['updated_at'] = $time;
            $requestData['main_id'] = $data['main_id'];
            $requestData['user_id'] = $data['user_id'];
            $requestData['upd_flag'] = $data['upd_flag'];
            $requestData['materiel_name'] = $data['materiel_name'];
            $requestData['materiel_class_id'] = $data['materiel_class_id'];
            $logData = '商品名称:' . $goodsName . '同步修改名称和分类，不包括其他属性';
        }
        $this->operateLog('同步修改物料商品', $data, $time, $logData);
        unset($data);
        return MaterielTypeService::syncEditMateriel($requestData, $this->getUserId());
    }

    /**
     * 同规格商品列表
     * @param Request $request
     * AUTHOR  : zlf
     * DateTime: 2023/9/13 9:39
     * @return \Illuminate\Http\JsonResponse
     */
    public function sameNameGoodsList(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'id' => 'required|integer',//物料id
            'pageSize' => 'required',//物料名称
            'currentPage' => 'required',//成本
        ],
            [
                'id.required' => '参数`物料商品id`缺失',
                'id.integer' => '参数`物料商品id`必须为整数',
                'pageSize.required' => '参数`页面大小`缺失',
                'currentPage.required' => '参数`页码`缺失',
            ]);

        if ($info = $validator->errors()->first()) {
            return fail('', $info);
        }
        return MaterielTypeService::sameNameGoodsList($data);
    }

    public function getBarcode(Request $request)
    {
        $year = substr(Carbon::parse()->year, -2);
        $orderNo = $year . mt_rand(100000000, 999999999);
        do {
            $orderNo = $year . mt_rand(100000000, 999999999);
        } while (!empty(MaterielTypeModel::query()->where([
            'bar_code' => $orderNo,
            'main_id' => $this->getMainUserId()
        ])->exists()));
        return response()->json(['code' => 0, 'msg' => 'success', 'data' => $orderNo]);
    }
}
